﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace SBWLogReader
{
    public class ViewBuilder
    {
   
        public DataTable GetRawDataTable(IEnumerable<LogEntry> logEntries, int bytesPerPacket, BandwidthUnit bandwidthUnit, List<string> excludedLogins)
        {           
            DataTable table = new DataTable();
            table.Columns.Add(new DataColumn("Log File", typeof(string)));
            table.Columns.Add(new DataColumn("Hour", typeof(int)));
            table.Columns.Add(new DataColumn("Login", typeof(string)));
            table.Columns.Add(new DataColumn("Packets_In", typeof(int)));
            table.Columns.Add(new DataColumn("Packets_Out", typeof(int)));
            table.Columns.Add(new DataColumn("Total_Packets", typeof(int)));
            table.Columns.Add(new DataColumn("Bandwidth_In", typeof(decimal)));
            table.Columns.Add(new DataColumn("Bandwidth_Out", typeof(decimal)));
            table.Columns.Add(new DataColumn("Total_Bandwidth", typeof(decimal)));
            table.Columns.Add(new DataColumn("Percent_Usage", typeof(decimal)));
            
            decimal totalBandwidthUsed = logEntries.Sum(l => l.TotalBandwidth(bandwidthUnit, bytesPerPacket, false));

            foreach (LogEntry entry in logEntries.OrderBy(l => l.Hour).ThenBy(l => l.Login))
            {
                DataRow row = table.NewRow();
                
                row[0] = entry.LogFile; 
                row[1] = entry.Hour; 
                row[2] = entry.Login;
                row[3] = entry.PacketsIn;
                row[4] = entry.PacketsOut;
                row[5] = entry.TotalPackets;
                row[6] = entry.BandwidthIn(bandwidthUnit, bytesPerPacket, true);
                row[7] = entry.BandwidthOut(bandwidthUnit, bytesPerPacket, true);
                row[8] = entry.TotalBandwidth(bandwidthUnit, bytesPerPacket, true);
                row[9] = decimal.Round(100 * entry.TotalBandwidth(bandwidthUnit, bytesPerPacket, false) / totalBandwidthUsed, 2); 

                table.Rows.Add(row);
            }
           
            return table;
        }

        public DataTable GetSummaryDataTable(IEnumerable<LogEntry> logEntries, int bytesPerPacket, BandwidthUnit bandwidthUnit, bool groupByHour)
        {
            DataTable table = new DataTable();
            decimal totalBandwidthUsed = logEntries.Sum(l => l.TotalBandwidth(bandwidthUnit, bytesPerPacket, false));

            if (groupByHour) { table.Columns.Add(new DataColumn("Hour", typeof(int))); }
            if (!groupByHour) { table.Columns.Add(new DataColumn("Login", typeof(string))); }
            table.Columns.Add(new DataColumn("Packets_In", typeof(int)));
            table.Columns.Add(new DataColumn("Packets_Out", typeof(int)));
            table.Columns.Add(new DataColumn("Total_Packets", typeof(int)));
            table.Columns.Add(new DataColumn("Bandwidth_In", typeof(decimal)));
            table.Columns.Add(new DataColumn("Bandwidth_Out", typeof(decimal)));
            table.Columns.Add(new DataColumn("Total_Bandwidth", typeof(decimal)));
            table.Columns.Add(new DataColumn("Percent_Usage", typeof(decimal)));

            if (groupByHour)
            {
                foreach (var group in logEntries.GroupBy(g => g.Hour))
                {
                    DataRow row = table.NewRow();                    
                    row[0] = group.Key;
                    row[1] = group.Sum(g => g.PacketsIn);
                    row[2] = group.Sum(g => g.PacketsOut);
                    row[3] = group.Sum(g => g.TotalPackets);
                    row[4] = group.Sum(g => g.BandwidthIn(bandwidthUnit, bytesPerPacket, true));
                    row[5] = group.Sum(g => g.BandwidthOut(bandwidthUnit, bytesPerPacket, true));
                    row[6] = group.Sum(g => g.TotalBandwidth(bandwidthUnit, bytesPerPacket, true));
                    row[7] = decimal.Round(100 * group.Sum(g => g.TotalBandwidth(bandwidthUnit, bytesPerPacket, false)) / totalBandwidthUsed, 2);

                    table.Rows.Add(row);
                }
            }
            else
            {
                foreach (var group in logEntries.GroupBy(g => g.Login))
                {
                    DataRow row = table.NewRow();                    
                    row[0] = group.Key;
                    row[1] = group.Sum(g => g.PacketsIn);
                    row[2] = group.Sum(g => g.PacketsOut);
                    row[3] = group.Sum(g => g.TotalPackets);
                    row[4] = group.Sum(g => g.BandwidthIn(bandwidthUnit, bytesPerPacket, true));
                    row[5] = group.Sum(g => g.BandwidthOut(bandwidthUnit, bytesPerPacket, true));
                    row[6] = group.Sum(g => g.TotalBandwidth(bandwidthUnit, bytesPerPacket, true));
                    row[7] = decimal.Round(100 * group.Sum(g => g.TotalBandwidth(bandwidthUnit, bytesPerPacket, false)) / totalBandwidthUsed, 2);

                    table.Rows.Add(row);
                }
            }

            // Add a totals row that sums up all data
            DataRow totalRow = table.NewRow();            
            totalRow[1] = logEntries.Sum(l => l.PacketsIn);
            totalRow[2] = logEntries.Sum(l => l.PacketsOut);
            totalRow[3] = logEntries.Sum(l => l.TotalPackets);
            totalRow[4] = decimal.Round(logEntries.Sum(l => l.BandwidthIn(bandwidthUnit, bytesPerPacket, false)), 2);
            totalRow[5] = decimal.Round(logEntries.Sum(l => l.BandwidthOut(bandwidthUnit, bytesPerPacket, false)), 2);
            totalRow[6] = decimal.Round(logEntries.Sum(l => l.TotalBandwidth(bandwidthUnit, bytesPerPacket, false)), 2);
            totalRow[7] = 100.00m;

            table.Rows.Add(totalRow);                

            return table;
        }      
    }
}
